package com.quanyan.ic.common.serialize;

import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;

/**
 * Created by zhuo.shi on 2017/7/31.
 * <p/>
 * Kryo 序列化工具类
 */
public class KryoSerializeUtils {

    private static final int bufferSize = 4096;
    private static final int maxBufferSize = 65536;

    public static byte[] serialize(Object object) {
        Kryo kryo = getKryo();
        Output output = null;
        try {
            output = new Output(bufferSize, maxBufferSize);
            kryo.writeClassAndObject(output, object);
            byte[] bytes = output.toBytes();
            output.flush();
            return bytes;
        } catch (Exception e) {
            throw e;
        }
    }


    public static <T> byte[] serialize(Object object, Class<T> type) {
        Kryo kryo = getKryo();
        Output output = null;
        try {
            output = new Output(bufferSize, maxBufferSize);
            kryo.writeObjectOrNull(output, object, type);
            byte[] bytes = output.toBytes();
            output.flush();
            return bytes;
        } catch (Exception e) {
            throw e;
        }
    }

    public static <T> T deserialize(byte[] bytes) {
        if (bytes == null) {
            return null;
        }
        try {
            Kryo kryo = getKryo();
            Input input = new Input(bytes);
            @SuppressWarnings("unchecked")
            T t = (T) kryo.readClassAndObject(input);
            input.close();
            return t;
        } catch (Exception e) {
            throw e;
        }
    }

    public static <T> T deserialize(byte[] bytes, Class<T> type) {
        if (bytes == null) {
            return null;
        }
        try {
            Kryo kryo = getKryo();
            Input input = new Input(bytes);
            T obj = kryo.readObject(input, type);
            input.close();
            return obj;
        } catch (Exception e) {
            throw e;
        }
    }

    private static Kryo getKryo() {
        Kryo kryo = new Kryo();
        kryo.setReferences(false);
        kryo.setRegistrationRequired(false);
        kryo.setClassLoader(KryoSerializeUtils.class.getClassLoader());
        return kryo;
    }
}
